home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Dialogs / LnkDlgEx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  63.5 KB  |  2,173 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LnkDlgEx.cpp
  3.  
  4.     Contains:    implementation of the Paste As and Link Info dialogs
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <4>      7/8/96    eeh        undo task 10008 (AppleGuide buttons)
  13.          <3>     6/21/96    eeh        task 10008: add buttons etc. for AppleGuide
  14.          <2>     6/21/96    RA        T10025: Call InitBndNSUtils
  15.         <1>     6/7/96 eeh        first checked in (based on LinkDlgs.cpp)
  16.  
  17.     In Progress:
  18.         
  19. */
  20.  
  21. #ifndef _PLFMDEF_
  22. #include <plfmdef.h>
  23. #endif
  24.  
  25. #ifndef _LINKDLGS_
  26. #include <LinkDlgs.h>
  27. #endif
  28.  
  29. #ifndef _INFOUTIL_
  30. #include <InfoUtil.h>
  31. #endif
  32.  
  33. #ifndef _DLOGUTIL_
  34. #include <DlogUtil.h>
  35. #endif
  36.  
  37. #ifndef _EXCEPT_
  38. #include <Except.h>
  39. #endif
  40.  
  41. #ifndef _LINKDEFS_
  42. #include <LinkDefs.h>
  43. #endif
  44.  
  45. #ifndef _USERSRCM_
  46. #include <UseRsrcM.h>
  47. #endif
  48.  
  49. #ifndef _AGSUPPORT_
  50. #include "AGSupprt.h"
  51. #endif
  52.  
  53. #ifndef SOM_Module_OpenDoc_StdProps_defined
  54. #include <StdProps.xh>
  55. #endif
  56.  
  57. #ifndef SOM_Module_OpenDoc_Foci_defined
  58. #include <Foci.xh>
  59. #endif
  60.  
  61. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  62. #include <StdTypes.xh>
  63. #endif
  64.  
  65. #ifndef SOM_ODTypeList_xh
  66. #include <TypeList.xh>
  67. #endif
  68.  
  69. #ifndef SOM_ODTypeListIterator_xh
  70. #include <TypLsItr.xh>
  71. #endif
  72.  
  73. #ifndef SOM_ODStorageUnit_xh
  74. #include <StorageU.xh>
  75. #endif
  76.  
  77. #ifndef SOM_ODPart_xh
  78. #include <Part.xh>
  79. #endif
  80.  
  81. #ifndef SOM_ODFrame_xh
  82. #include <Frame.xh>
  83. #endif
  84.  
  85. #ifndef SOM_ODFacet_xh
  86. #include <Facet.xh>
  87. #endif
  88.  
  89. #ifndef SOM_ODBaseLink_xh
  90. #include <LinkB.xh>
  91. #endif
  92.  
  93. #ifndef SOM_ODBaseLinkSource_xh
  94. #include <LinkSrcB.xh>
  95. #endif
  96.  
  97. #ifndef SOM_ODBinding_xh
  98. #include <ODBindng.xh>
  99. #endif
  100.  
  101. #ifndef SOM_ODTranslation_xh
  102. #include <Translt.xh>
  103. #endif
  104.  
  105. #ifndef SOM_ODWindowState_xh
  106. #include <WinStat.xh>
  107. #endif
  108.  
  109. #ifndef _BINDNGH_
  110. #include <BindngH.h>
  111. #endif
  112.  
  113. #ifndef _BNDNSUTL_
  114. #include <BndNSUtl.h>
  115. #endif
  116.  
  117. #ifndef SOM_ODSession_xh
  118. #include <ODSessn.xh>
  119. #endif
  120.  
  121. #ifndef SOM_ODArbitrator_xh
  122. #include <Arbitrat.xh>
  123. #endif
  124.  
  125. #ifndef SOM_ODDispatcher_xh
  126. #include <Disptch.xh>
  127. #endif
  128.  
  129. #ifndef _ODUTILS_
  130. #include <ODUtils.h>
  131. #endif
  132.  
  133. #ifndef _PASCLSTR_
  134. #include <PasclStr.h>
  135. #endif
  136.  
  137. #ifndef _ISOSTR_
  138. #include <ISOStr.h>
  139. #endif
  140.  
  141. #ifndef _DOCUTILS_
  142. #include <DocUtils.h>
  143. #endif
  144.  
  145. #ifndef _ODMEMORY_
  146. #include <ODMemory.h>
  147. #endif
  148.  
  149. #ifdef __SC__
  150. #ifndef __PACKAGES__
  151. #include <Packages.h>
  152. #endif
  153. #else
  154. #ifndef __TEXTUTILS__
  155. #include <TextUtils.h>
  156. #endif
  157. #endif
  158.  
  159. #ifndef __STRING__
  160. #include <String.h>
  161. #endif
  162.  
  163. #ifndef __GESTALTEQU__
  164. #include <GestaltEqu.h>
  165. #endif
  166.  
  167. #ifndef __DIALOGS__
  168. #include <Dialogs.h>
  169. #endif
  170.  
  171. #ifndef __TOOLUTILS__
  172. #include <ToolUtils.h>
  173. #endif
  174.  
  175. #ifndef __FONTS__
  176. #include <Fonts.h>
  177. #endif
  178.  
  179. #ifndef __CONTROLS__
  180. #include <Controls.h>
  181. #endif
  182.  
  183. #ifndef __RESOURCES__
  184. #include <Resources.h>
  185. #endif
  186.  
  187. #ifndef _TRANSUTL_
  188. #include <TransUtl.h>
  189. #endif
  190.  
  191. #ifndef __LISTS__
  192. #include <Lists.h>
  193. #endif
  194.  
  195. #ifndef __PALETTES__
  196. #include <Palettes.h>
  197. #endif
  198.  
  199. #ifndef _STORUTIL_
  200. #include <StorUtil.h>
  201. #endif
  202.  
  203. #ifndef _EDITRSET_
  204. #include <EditrSet.h>
  205. #endif
  206.  
  207. #ifndef _STDTYPIO_
  208. #include <StdTypIO.h>
  209. #endif
  210.  
  211. #ifndef _TEMPOBJ_
  212. #include <TempObj.h>
  213. #endif
  214.  
  215. #ifndef _ORDCOLL_
  216. #include "OrdColl.h"
  217. #endif
  218.  
  219. #ifndef SOM_ODStorageSystem_xh
  220. #include "ODStor.xh"
  221. #endif
  222.  
  223. #pragma segment Info
  224.  
  225. #if ODDebug
  226. #define ODDebugLinkDlgs 0
  227. #else
  228. #define ODDebugLinkDlgs 0
  229. #endif
  230.  
  231. //==============================================================================
  232. // Global variables
  233. //==============================================================================
  234.  
  235. // Use a global to pass the current session to the LinkFilterProc
  236. // Globals are per process, and there is only one session per process.
  237. //static ODSession* gSession = kODNULL;
  238.  
  239. static ODName* gKindName = kODNULL;
  240. static ODName* gEditorName = kODNULL;
  241. static ODName* gEmbeddedEditorName = kODNULL;
  242.  
  243. //==============================================================================
  244. // Constants
  245. //==============================================================================
  246.  
  247. const Boolean kNoDefaultButton = kODFalse;
  248.  
  249. const short kButtonFrameInset = -4;
  250.  
  251. const short kControlInactive = 255;
  252. const short kControlActive = 0;
  253.  
  254. // Constants used in list manager calls
  255. const Boolean kDoDraw = true;
  256. const Boolean kNoGrow = false;
  257. const Boolean kIncludeScrollBar = true;
  258.  
  259. // Key codes
  260. // <eeh> moved to DlogUtil.h
  261. // const char kEnterKey        = 0x03;
  262. // const char kReturnKey        = 0x0D;
  263. // const char kEscapeKey        = 0x1B;
  264. // const char kUpArrowKey        = 0x1E;
  265. // const char kDownArrowKey    = 0x1F;
  266.  
  267. //==============================================================================
  268. // Scalar types
  269. //==============================================================================
  270. typedef char ODHandleState;
  271.  
  272. //==============================================================================
  273. // Function declarations
  274. //==============================================================================
  275. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name);
  276.  
  277. ODStatic void SetDateTimeStrings(
  278.                     ODULong        dateTime,
  279.                     Str255        dateString, 
  280.                     Str255        timeString);
  281.  
  282. ODStatic void InitItemActive(
  283.                     DialogPtr    dlg,
  284.                     short        itemNumber,
  285.                     UserItemUPP    itemUPP,
  286.                     ODBoolean    itemActive);
  287.  
  288. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem);
  289.  
  290. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su);
  291.  
  292. ODStatic void SetControlActive(
  293.                     DialogPtr    dlg,
  294.                     short        itemNumber,
  295.                     ODBoolean    itemActive);
  296.  
  297. ODStatic ODType BestContentKind(ODStorageUnit* contentSU);
  298.  
  299. ODStatic pascal void DrawKindName(DialogPtr dialog, SInt16 item);
  300. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item);
  301.  
  302. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  303.                                 ODUShort kindIndex,
  304.                                 ODTypeList* translateToList,
  305.                                 ODUShort translateToIndex,
  306.                                 EditorSet* editorList,
  307.                                 MenuHandle editorMenu, 
  308.                                 ControlHandle popupCtlHndl, 
  309.                                 ODSession* session);
  310.  
  311. static pascal Boolean
  312. PasteAsFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit);
  313.  
  314. ODStatic void SetPopupControlValue(ControlHandle popupControlHandle, short itemValue);
  315.  
  316. #ifdef __cplusplus
  317. extern "C" {
  318. #endif
  319.  
  320. ODError ShowPasteAsDialogEx(
  321.                 ODBoolean                canPasteLink,
  322.                 ODPasteAsMergeSetting    mergeSetting,
  323.                 ODBoolean                isMove,
  324.                 ODStorageUnit*            contentSU,
  325.                 ODFacet*                facet,
  326.                 ODTypeToken                viewType,
  327.                 ODPasteAsResult*        result,
  328.                 ODBoolean*                boolResult);
  329.  
  330. ODError ShowLinkSourceInfoEx(
  331.                 ODBaseLinkSource*    linkSource,
  332.                 ODUpdateID            change,
  333.                 ODBoolean            changesAllowed,
  334.                 ODLinkInfoResult*    infoResult,
  335.                 ODBoolean*            boolResult);
  336.  
  337. ODError ShowLinkDestinationInfoEx(
  338.                 ODBaseLink*            link,
  339.                 ODLinkInfo*         info,
  340.                 ODBoolean            changesAllowed,
  341.                 ODLinkInfoResult*    infoResult,
  342.                 ODBoolean*                boolResult);
  343.  
  344. #ifdef __cplusplus
  345. }
  346. #endif
  347.  
  348. //------------------------------------------------------------------------------
  349. // DisposeGlobalODNameAndZeroPtr
  350. //------------------------------------------------------------------------------
  351. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name)
  352. {
  353.     if (*name)
  354.     {
  355.         // simple way to force deletion of old name value without knowing
  356.         // that DisposeIText is the right way to destroy an ODName:
  357.         TempODName tempName = *name;
  358.         *name = kODNULL;
  359.     }
  360. }
  361.  
  362. //------------------------------------------------------------------------------
  363. // DrawEditorName
  364. //------------------------------------------------------------------------------
  365.  
  366. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item)
  367. {
  368.     short            itemType;
  369.     Handle            itemHandle;
  370.     Rect            itemRect;
  371.  
  372.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  373.  
  374.     if ( gEditorName )
  375.         DrawITextInDlogBox(gEditorName, &itemRect, dialog, kODTrue);
  376. }
  377.  
  378. //------------------------------------------------------------------------------
  379. // DrawEmbeddedEditorName
  380. //------------------------------------------------------------------------------
  381.  
  382. ODStatic pascal void DrawEmbeddedEditorName(DialogPtr dialog, SInt16 item)
  383. {
  384.     short            itemType;
  385.     Handle            itemHandle;
  386.     Rect            itemRect;
  387.  
  388.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  389.  
  390.     if ( gEmbeddedEditorName )
  391.         DrawITextInDlogBox(gEmbeddedEditorName, &itemRect, dialog, kODTrue);
  392. }
  393.  
  394. //------------------------------------------------------------------------------
  395. // GetSelectedType
  396. //------------------------------------------------------------------------------
  397. // $$$$$ Should be replaced by GetThisKindFromList in InfoUtil.h
  398.  
  399. ODStatic ODType GetSelectedType(ODTypeList* typeList, ODSShort typeIndex)
  400. {
  401.     Environment*        ev = somGetGlobalEnvironment();
  402.     ODType                type = kODNULL;
  403.     ODTypeListIterator*    iter = typeList->CreateTypeListIterator(ev);
  404.     
  405.     for ( type = iter->First(ev); 
  406.           (--typeIndex > 0) && iter->IsNotComplete(ev); 
  407.           type = iter->Next(ev) )
  408.     {
  409.         ODDisposePtr(type);
  410.         type = kODNULL;
  411.     }
  412.  
  413.     delete iter;
  414.     
  415.     return type;
  416. }
  417.  
  418. //------------------------------------------------------------------------------
  419. // GetSelectedEditor
  420. //------------------------------------------------------------------------------
  421.  
  422. ODStatic ODEditor GetSelectedEditor(EditorSet* editorList, ODSShort editorIndex)
  423. {
  424.     ODEditor            editor;
  425.     EditorSetIterator*    iter = editorList->CreateIterator();
  426.     
  427.     for ( editor = iter->First(); 
  428.           (--editorIndex > 0) && iter->IsNotComplete(); 
  429.           editor = iter->Next() )
  430.     {
  431.     }
  432.  
  433.     delete iter;
  434.     
  435.     if ( editor != kODNULL )
  436.         editor = ODISOStrFromCStr((char *) editor);
  437.  
  438.     return editor;
  439. }
  440.  
  441. //------------------------------------------------------------------------------
  442. // EnableKindPopupItems
  443. //------------------------------------------------------------------------------
  444.  
  445. ODStatic void EnableKindPopupItems(
  446.                     ODBoolean            forMerge,
  447.                     ODTypeList*            typeList,
  448.                     ODTypeList*            translateList,
  449.                     ODSShort            translationIndex,
  450.                     MenuHandle            kindMenu,
  451.                     ODEditor            editor,
  452.                     ODNameSpaceManager*    nsm)
  453. {
  454.     Environment* ev = somGetGlobalEnvironment();
  455.  
  456.     ODUShort item = EnableTypesInMenu(typeList, kindMenu, forMerge ? editor : kODNULL, nsm);
  457.  
  458.     // If a translation choice is present in the popup, enable it if appropriate;
  459.     if ( translationIndex != 0 )
  460.     {
  461.         TempODType translationKind = GetSelectedType(translateList, translationIndex);
  462.  
  463.         if ( !forMerge || EditorSupportsKind(nsm, editor, translationKind) )
  464.             EnableItem(kindMenu, ++item);
  465.         else
  466.             DisableItem(kindMenu, ++item);
  467.     }
  468.  
  469.     // Enable the "Translate to…" item in the kind popup if translation is possible
  470.     if ( translateList->Count(ev) > 0 )
  471.         EnableItem(kindMenu, ++item);
  472.     else
  473.         DisableItem(kindMenu, ++item);
  474. }
  475.  
  476. //------------------------------------------------------------------------------
  477. // EnablePasteAsOkButton
  478. //------------------------------------------------------------------------------
  479.  
  480. ODStatic void EnablePasteAsOkButton(DialogPtr dlog, MenuHandle kindMenu)
  481. {
  482.     Environment*    ev = somGetGlobalEnvironment();
  483.     short            itemType;
  484.     Handle            itemHandle;
  485.     Rect            itemRect;
  486.     ODSShort        kindItemSelected;
  487.     ODBoolean        shouldBeEnabled;
  488.  
  489.     GetDialogItem(dlog, kPasteAsKindPopup, &itemType, &itemHandle, &itemRect);
  490.     ASSERT_CONTROL_ITEM(itemType);
  491.     kindItemSelected = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  492.  
  493.     // Only the first 31 items of a menu may be disabled
  494.     if ( kindItemSelected > 31 )
  495.         shouldBeEnabled = kODTrue;
  496.     else
  497.         // BitTst numbers the bits hi to low
  498.         shouldBeEnabled = BitTst(&(**kindMenu).enableFlags, 31-kindItemSelected);
  499.  
  500.     EnableOkButton(dlog, shouldBeEnabled);
  501. }
  502.  
  503. //------------------------------------------------------------------------------
  504. // BestMergeKindSetting
  505. //------------------------------------------------------------------------------
  506.  
  507. ODStatic ODSShort BestMergeKindSetting(
  508.                     ODTypeList*            kinds,
  509.                     ODType                bestKind,
  510.                     ODEditor            editor,
  511.                     ODNameSpaceManager*    nsm)
  512. {
  513.     if ( bestKind && EditorSupportsKind(nsm, editor, bestKind) )
  514.         return IndexOfKindInList(kinds, bestKind);
  515.     
  516.     Environment*        ev = somGetGlobalEnvironment();
  517.     ODSShort            kindItem = 0;        // Default in case none are supported
  518.  
  519.     ODTypeListIterator*    iter = kinds->CreateTypeListIterator(ev);
  520.     
  521.     ODType                type;
  522.     ODSShort            i;
  523.     for ( type = iter->First(ev), i = 1; 
  524.           iter->IsNotComplete(ev); 
  525.           type = iter->Next(ev), ++i )
  526.     {
  527.         ODBoolean supports = EditorSupportsKind(nsm, editor, type);
  528.         ODDisposePtr(type);
  529.         if ( supports )
  530.         {
  531.             kindItem = i;
  532.             break;
  533.         }
  534.     }
  535.  
  536.     delete iter;
  537.     
  538.     return kindItem;
  539. }
  540.  
  541. //------------------------------------------------------------------------------
  542. // InitialViewSelection
  543. //------------------------------------------------------------------------------
  544. ODStatic void InitialViewSelection(DialogPtr dlg, ODTypeToken viewType, ODSession* session)
  545. {
  546.     short        itemType;
  547.     Handle        itemHandle;
  548.     Rect        itemRect;
  549.     ODSShort    viewItem;
  550.     
  551.     Environment* ev = somGetGlobalEnvironment();
  552.  
  553.     if (viewType == session->Tokenize(ev, kODViewAsFrame))
  554.         viewItem = kODPasteAsFrameMenuItem;
  555.     else if (viewType == session->Tokenize(ev, kODViewAsLargeIcon))
  556.         viewItem = kODPasteAsLargeIconMenuItem;
  557.     else if (viewType == session->Tokenize(ev, kODViewAsSmallIcon))
  558.         viewItem = kODPasteAsSmallIconMenuItem;
  559.     else if (viewType == session->Tokenize(ev, kODViewAsThumbnail))
  560.         viewItem = kODPasteAsThumbnailMenuItem;
  561.     else
  562.         viewItem = kODPasteAsFrameMenuItem;
  563.  
  564.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  565.     ASSERT_CONTROL_ITEM(itemType);
  566.     SetControlValue((ControlHandle)itemHandle, viewItem);
  567. }
  568.  
  569. //------------------------------------------------------------------------------
  570. // GetViewSelected
  571. //------------------------------------------------------------------------------
  572. ODStatic ODTypeToken GetViewSelected(DialogPtr dlg, ODSession* session)
  573. {
  574.     short        itemType;
  575.     Handle        itemHandle;
  576.     Rect        itemRect;
  577.  
  578.     Environment* ev = somGetGlobalEnvironment();
  579.  
  580.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  581.     ASSERT_CONTROL_ITEM(itemType);
  582.     ODSShort viewItem = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  583.     ODType viewAs;
  584.     switch ( viewItem )
  585.     {
  586.     case kODPasteAsLargeIconMenuItem:
  587.             viewAs = kODViewAsLargeIcon;
  588.             break;
  589.     case kODPasteAsSmallIconMenuItem:
  590.             viewAs = kODViewAsSmallIcon;
  591.             break;
  592.     case kODPasteAsThumbnailMenuItem:
  593.             viewAs = kODViewAsThumbnail;
  594.             break;
  595.     default:
  596.             viewAs = kODViewAsFrame;
  597.             break;
  598.     }
  599.  
  600.     return session->Tokenize(ev, viewAs);
  601. }
  602.  
  603. //------------------------------------------------------------------------------
  604. // HaveColorQuickdraw
  605. //------------------------------------------------------------------------------
  606. ODStatic ODBoolean HaveColorQuickdraw()
  607. {
  608.     long response;
  609.  
  610.     Gestalt(gestaltQuickdrawFeatures, &response);
  611.         
  612.     /* check if Color QuickDraw is available */    
  613.     return BitTst(&response, 31-gestaltHasColor);
  614. }
  615.  
  616. //------------------------------------------------------------------------------
  617. // EnableDialogItem
  618. //------------------------------------------------------------------------------
  619. ODStatic void EnableDialogItem(DialogPtr dlg, short itemNumber, ODBoolean enable)
  620. {
  621.     short        itemType;
  622.     Handle        itemHandle;
  623.     Rect        itemRect;
  624.  
  625.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  626.     if ( enable )
  627.         itemType &= ~itemDisable;
  628.     else
  629.         itemType |= itemDisable;
  630.     SetDialogItem(dlg, itemNumber, itemType, itemHandle, &itemRect);
  631. }
  632.  
  633. //------------------------------------------------------------------------------
  634. // InvalDialogItem
  635. //------------------------------------------------------------------------------
  636. ODStatic void InvalDialogItem(DialogPtr dlg, short itemNumber)
  637. {
  638.     short        itemType;
  639.     Handle        itemHandle;
  640.     Rect        itemRect;
  641.     WindowPtr    savePort;
  642.  
  643.     GetPort(&savePort);
  644.     SetPort(dlg);
  645.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);    
  646.     InvalRect(&itemRect);
  647.     SetPort(savePort);
  648. }
  649.  
  650. //------------------------------------------------------------------------------
  651. // SetPopupControlValue
  652. //------------------------------------------------------------------------------
  653. ODStatic void SetPopupControlValue(ControlHandle popupControlHandle, short itemValue)
  654. {
  655.     // The resource file must be in the chain in order for the popup to redraw.
  656.     CUsingLibraryResources r;
  657.     SetControlValue(popupControlHandle, itemValue);
  658. }
  659.  
  660. //------------------------------------------------------------------------------
  661. // SetupControlItem
  662. //------------------------------------------------------------------------------
  663. ODStatic void SetupControlItem(
  664.                     DialogPtr    dlg,
  665.                     short        itemNumber,
  666.                     short        itemValue,
  667.                     ODBoolean    itemActive)
  668. {
  669.     short        itemType;
  670.     Handle        itemHandle;
  671.     Rect        itemRect;
  672.  
  673.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  674.     ASSERT_CONTROL_ITEM(itemType);
  675.     SetControlValue((ControlHandle)itemHandle, itemActive? itemValue : 0);
  676.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  677. }
  678.  
  679. //------------------------------------------------------------------------------
  680. // InactivateEmbedAsPopup
  681. //------------------------------------------------------------------------------
  682.  
  683. ODStatic void InactivateEmbedAsPopup(DialogPtr dlg)
  684. // Set clipping to just the display area of the popup so the radio button
  685. // label isn't dimmed.
  686. {
  687.     short        aItem;
  688.     Handle        aHandle;
  689.     Handle        embedPopupCntlHandle;
  690.     Rect        aRect;
  691.     RgnHandle    embedTextRgn = ODNewRgn();
  692.     RgnHandle    embedPopupRgn = ODNewRgn();
  693.     RgnHandle    clipRgn = ODNewRgn();
  694.  
  695.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &aItem, &aHandle, &aRect);
  696.     RectRgn(embedTextRgn,&aRect);
  697.  
  698.     GetDialogItem(dlg, kPasteAsEmbedPopup, &aItem, &embedPopupCntlHandle, &aRect);
  699.     RectRgn(embedPopupRgn,&aRect);
  700.  
  701.     GetClip(clipRgn);
  702.     DiffRgn(embedPopupRgn, embedTextRgn, embedPopupRgn);
  703.     SetClip(embedPopupRgn);
  704.     HiliteControl((ControlHandle)embedPopupCntlHandle, kControlInactive);
  705.     SetClip(clipRgn);
  706.     
  707.     ODDisposeHandle((Handle)clipRgn);
  708.     ODDisposeHandle((Handle)embedPopupRgn);
  709.     ODDisposeHandle((Handle)embedTextRgn);
  710. }
  711.  
  712. //------------------------------------------------------------------------------
  713. // ClipOutRect
  714. //------------------------------------------------------------------------------
  715.  
  716. ODStatic RgnHandle ClipOutRect(Rect* r)
  717. {
  718.     RgnHandle    saveRgn = ODNewRgn();
  719.     RgnHandle    rectRgn = ODNewRgn();
  720.     RgnHandle    clipRgn = ODNewRgn();
  721.  
  722.     GetClip(saveRgn);
  723.  
  724.     RectRgn(rectRgn, r);
  725.  
  726.     GetClip(clipRgn);
  727.     DiffRgn(clipRgn, rectRgn, clipRgn);
  728.     SetClip(clipRgn);
  729.  
  730.     ODDisposeHandle((Handle)rectRgn);
  731.     ODDisposeHandle((Handle)clipRgn);
  732.     
  733.     return saveRgn;
  734. }
  735.  
  736. //------------------------------------------------------------------------------
  737. // SetAutomaticUpdateControls
  738. //------------------------------------------------------------------------------
  739. ODStatic void SetAutomaticUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  740. {
  741.     short    itemType;
  742.     Handle    itemHandle;
  743.     Rect    itemRect;
  744.  
  745.     GetDialogItem(dlg, kPasteAsAutomaticRadioBtn, &itemType, &itemHandle, &itemRect);
  746.     ASSERT_CONTROL_ITEM(itemType);
  747.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  748.     GetDialogItem(dlg, kPasteAsManualRadioBtn, &itemType, &itemHandle, &itemRect);
  749.     ASSERT_CONTROL_ITEM(itemType);
  750.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  751. }
  752.  
  753. //------------------------------------------------------------------------------
  754. // SetMergeEmbedControls
  755. //------------------------------------------------------------------------------
  756. ODStatic void SetMergeEmbedControls(DialogPtr dlg, ODBoolean mergeSetting)
  757. {
  758.     short    itemType;
  759.     Handle    itemHandle;
  760.     Rect    itemRect;
  761.  
  762.     CUsingLibraryResources r;    // Necessary to change embed popup
  763.  
  764.     GetDialogItem(dlg, kPasteAsMergeRadioBtn, &itemType, &itemHandle, &itemRect);
  765.     ASSERT_CONTROL_ITEM(itemType);
  766.     SetControlValue((ControlHandle)itemHandle, mergeSetting);
  767.     
  768.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &itemType, &itemHandle, &itemRect);
  769.     ASSERT_CONTROL_ITEM(itemType);
  770.     SetControlValue((ControlHandle)itemHandle, !mergeSetting);
  771.  
  772.     if ( mergeSetting )
  773.     {
  774.         InactivateEmbedAsPopup(dlg);
  775.     }
  776.     else
  777.     {
  778.         GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  779.         ASSERT_CONTROL_ITEM(itemType);
  780.         HiliteControl((ControlHandle)itemHandle, kControlActive);
  781.     }
  782. }
  783.  
  784. //------------------------------------------------------------------------------
  785. // GetIndexedElement
  786. //------------------------------------------------------------------------------
  787.  
  788. ODStatic ODULong GetIndexedElement(OrderedCollection* translateFromList, ODULong translationIndex)
  789. {
  790.     OrderedCollectionIterator* oci = translateFromList->CreateIterator();
  791.  
  792.     ODULong elem = 0;
  793.  
  794.     for (    elem = (ODULong) oci->First();
  795.             oci->IsNotComplete(); 
  796.             elem = (ODULong) oci->Next() )
  797.     {
  798.         if ( --translationIndex == 0 )
  799.             break;
  800.     }
  801.  
  802.     ODDeleteObject(oci);
  803.  
  804.     return elem;
  805. }
  806.  
  807. //------------------------------------------------------------------------------
  808. // GetOriginalDraft
  809. //------------------------------------------------------------------------------
  810. // Returns 0 if the original draft is unknown.  This is the case when content
  811. // was placed in the draft without cloning.  This code is dependent on properties
  812. // created by the argument storage unit's container suite.
  813.  
  814.  
  815. static ODULong GetOriginalDraft(Environment* ev, ODDraft* draft)
  816. {
  817.     TempODStorageUnit    draftProperties = draft->AcquireDraftProperties(ev);
  818.     return ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
  819. }
  820.  
  821. //------------------------------------------------------------------------------
  822. // SUClonedFromDraft
  823. //------------------------------------------------------------------------------
  824. // Returns kODTrue is the argument storage unit is the clone of a storage unit
  825. // from the argument draft.  This code is dependent on properties created by
  826. // the argument storage unit's container suite.
  827.  
  828. static ODBoolean SUClonedFromDraft(Environment* ev,
  829.             ODStorageUnit* su,
  830.             ODDraft* draft)
  831. {
  832.     return ((ODDraft*)GetOriginalDraft(ev, su->GetDraft(ev)) == draft &&
  833.             su->Exists(ev, kODPropOriginalID, kODULong, 0));
  834. }
  835.  
  836. //------------------------------------------------------------------------------
  837. // DeactivateModalDialog
  838. //------------------------------------------------------------------------------
  839.  
  840. ODStatic void DeactivateModalDialog(ModalFilterUPP filterProc)
  841. {
  842.     DialogPtr dialog = (DialogPtr) FrontWindow();
  843.  
  844.     if ( dialog )
  845.     {
  846.         EventRecord event;
  847.         
  848.         event.what = activateEvt;
  849.         event.message = (long) dialog;
  850.         event.modifiers = 0;
  851.  
  852.         CallModalFilterProc(filterProc, dialog, &event, 0);
  853.     }
  854. }
  855.  
  856. //------------------------------------------------------------------------------
  857. // PasteAsFilterProc
  858. //------------------------------------------------------------------------------
  859.  
  860. static pascal Boolean
  861. PasteAsFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit)
  862. {    
  863.     // If the event is a deactivate event, the ok button must be deactivated
  864.     // before the surrounding outline is drawn so it is drawn dim.
  865.     ODBoolean rslt = ODButtonKeyFilterProc(dialog,event,itemHit);
  866.  
  867.     if ( event->what == activateEvt )
  868.     {
  869.         ODOutlineDefaultButtonDrawProc(dialog, kPasteAsDefaultButtonItem);
  870.     }
  871.  
  872.     return rslt;
  873. }
  874.  
  875. //------------------------------------------------------------------------------
  876. // ShowPasteAsDialog
  877. //------------------------------------------------------------------------------
  878.  
  879. ODError ShowPasteAsDialogEx(
  880.                 ODBoolean                canPasteLink,
  881.                 ODPasteAsMergeSetting    mergeSetting,
  882.                 ODBoolean                isMove,
  883.                 ODStorageUnit*            contentSU,
  884.                 ODFacet*                facet,
  885.                 ODTypeToken                viewType,
  886.                 ODPasteAsResult*        result,
  887.                 ODBoolean*            boolResult)
  888.  
  889. {
  890.     Environment* ev = somGetGlobalEnvironment();
  891.     ODError err = noErr;
  892.  
  893.     WindowPtr    savePort;                            ODVolatile(savePort);
  894.     GetPort(&savePort);
  895.  
  896.     short          itemHit = kPasteAsCancelBtn;
  897.     short        itemType;
  898.     DialogPtr      dlg = kODNULL;                        ODVolatile(dlg);
  899.     Handle        itemHandle;
  900.     Rect        itemRect;
  901.     Rect        kindPopupRect;
  902.     Rect        editorPopupRect;
  903.     short        kindItemSelected;
  904.     short        kindItemOthers;
  905.     short        kindItemCurrent;
  906.     ODBoolean    kindPopupHasNoTranslationKind = kODTrue;
  907.     ODUShort    translationIndex = 0;
  908.  
  909.     ODSLong        refSaved;
  910.     OSErr        resErr;
  911.  
  912.     ODBoolean    userChangedKind = kODFalse;
  913.  
  914.     ControlHandle kindPopupControlHandle;
  915.     ControlHandle editorPopupControlHandle;
  916.  
  917.     ODEditor mergeEditorID = kODNULL;                ODVolatile(mergeEditorID);
  918.     ODEditor embedEditorID = kODNULL;                ODVolatile(embedEditorID);
  919.     ODEditor preferredEditorID = kODNULL;            ODVolatile(preferredEditorID);
  920.  
  921.     EditorSet* editorList = kODNULL;                ODVolatile(editorList);
  922.  
  923.     ODSShort bestKindIndex = 1;
  924.     ODSShort bestMergeKind = 1;
  925.  
  926.     ODType bestKind = kODNULL;                        ODVolatile(bestKind);
  927.     ODTypeList*    kindList = kODNULL;                    ODVolatile(kindList);
  928.     ODTypeList*    translateToList = kODNULL;            ODVolatile(translateToList);
  929.     OrderedCollection* translateFromList = kODNULL;    ODVolatile(translateFromList);
  930.  
  931.     MenuHandle kindMenu = kODNULL;                    ODVolatile(kindMenu);
  932.     MenuHandle editorMenu = kODNULL;                ODVolatile(editorMenu);
  933.  
  934.     UserItemUPP DrawBoxItemUPP = kODNULL;            ODVolatile(DrawBoxItemUPP);
  935.     UserItemUPP DrawDeactiveItemUPP = kODNULL;        ODVolatile(DrawDeactiveItemUPP);
  936.     UserItemUPP    DrawEditorNameUPP = kODNULL;        ODVolatile(DrawEditorNameUPP);
  937.     UserItemUPP    DrawEmbeddedEditorNameUPP = kODNULL;ODVolatile(DrawEmbeddedEditorNameUPP);
  938.     UserItemUPP    DrawKindNameUPP = kODNULL;            ODVolatile(DrawKindNameUPP);
  939.  
  940.     ModalFilterUPP modalFilter = kODNULL;            ODVolatile(modalFilter);
  941.  
  942.     if ( canPasteLink )
  943.         canPasteLink = contentSU->Exists(ev, kODPropLinkSpec, (ODValueType) kODLinkSpec, 0);
  944.  
  945.     result->pasteLinkSetting = (!isMove) && canPasteLink;
  946.     result->autoUpdateSetting = kODTrue;
  947.     result->selectedKind = (ODType) kODNULL;
  948.     result->translateKind = (ODType) kODNULL;
  949.     result->editor = kODNoEditor;
  950.  
  951.     ODSession* session;
  952.     {
  953.         TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  954.         session = part->GetStorageUnit(ev)->GetSession(ev);
  955.     }
  956.  
  957.     
  958.     TRY
  959.         ODBinding* binding = session->GetBinding(ev);
  960.         InitBindingNamespaceUtils(session);
  961.         
  962.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  963.  
  964.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  965.  
  966.         { TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  967.           mergeEditorID = GetCurrentEditorForPart(part);
  968.         }
  969.         
  970.         kindList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  971.         ContentValueTypes(contentSU, kindList);
  972.         
  973.         // Now get all possible translations from the available kinds
  974.         translateToList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  975.         translateFromList = new OrderedCollection;
  976.         TranslateValueTypes(kindList, translateToList, translateFromList, session);
  977.         
  978.         refSaved = BeginUsingLibraryResources();
  979.         kindMenu = GetMenu(kPasteAsKindPopupMenu);
  980.         resErr = ResError();
  981.         EndUsingLibraryResources(refSaved);
  982.         THROW_IF_NULL(kindMenu, resErr ? resErr : resNotFound);
  983.     
  984.         AddTypesToMenu(kindList, kindMenu, kODNULL, kODNULL, session);
  985.         kindItemOthers = CountMItems(kindMenu);
  986.  
  987.         ODBoolean canMerge = (mergeSetting != kODPasteAsEmbedOnly);
  988.         ODBoolean canEmbed = (mergeSetting != kODPasteAsMergeOnly);
  989.  
  990.         result->mergeSetting = (mergeSetting == kODPasteAsMerge) || (mergeSetting == kODPasteAsMergeOnly);
  991.  
  992.         {
  993.             CUsingLibraryResources r;
  994.             dlg = ODGetNewDialog(ev, kPasteAsDlgID, session, kNoDefaultButton);
  995.             THROW_IF_NULL(dlg);
  996.             SetPort(dlg);
  997.             SetDialogTextStyle(dlg, kPasteAsDlgID, smCurrentScript);
  998.         }
  999.     
  1000.         DialogSetUpAppleGuide( dlg, kPasteAsAGButton );
  1001.     
  1002.         /* Horizontal line needs to be drawn */
  1003.         GetDialogItem(dlg, kPasteAsHorizSep, &itemHit, &itemHandle, &itemRect);
  1004.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  1005.         SetDialogItem(dlg, kPasteAsHorizSep, itemHit, (Handle)DrawBoxItemUPP, &itemRect);
  1006.     
  1007.         // Set the draw routine for the default button outline item
  1008.         GetDialogItem(dlg, kPasteAsDefaultButtonItem, &itemHit, &itemHandle, &itemRect);
  1009.         SetDialogItem(dlg, kPasteAsDefaultButtonItem, itemHit, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  1010.         
  1011.         // Create one UPP for all user items used to draw deactive PICTs
  1012.         DrawDeactiveItemUPP = NewUserItemProc(DrawDeactivePICTItem);
  1013.  
  1014.         // Initialize state of "Paste with Link" checkbox and label
  1015.         SetupControlItem(dlg, kPasteAsLinkCheckbox, result->pasteLinkSetting, canPasteLink);
  1016.         
  1017.         // Initialize state of "Get Updates" radio buttons and labels
  1018.         if ( result->pasteLinkSetting)
  1019.             HideDialogItem(dlg, kPasteAsUpdateDisabledText);
  1020.         else
  1021.             HideDialogItem(dlg, kPasteAsUpdateText);
  1022.  
  1023.         SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  1024.         SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  1025.  
  1026.         // set up merge picture, radio button, and label
  1027.         InitItemActive(dlg, kPasteAsMergePict, DrawDeactiveItemUPP, canMerge);
  1028.         SetupControlItem(dlg, kPasteAsMergeRadioBtn, result->mergeSetting, canMerge);
  1029.  
  1030.         // set up embed picture, radio button, and label
  1031.         InitItemActive(dlg, kPasteAsEmbedPict, DrawDeactiveItemUPP, canEmbed);
  1032.         SetupControlItem(dlg, kPasteAsEmbedRadioBtn, !result->mergeSetting, canEmbed);
  1033.     
  1034.         // set up initial "Paste as:" popup selection
  1035.         InitialViewSelection(dlg, viewType, session);
  1036.  
  1037.         // inactivate the "Embed as:" popup if merge is initially selected
  1038.         if ( result->mergeSetting )
  1039.         {
  1040.             GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  1041.             ASSERT_CONTROL_ITEM(itemType);
  1042.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  1043.         }
  1044.  
  1045.         // Determine the indices of the best kind and the best kind that can be merged
  1046.         bestKind = BestContentKind(contentSU);
  1047.         if ( bestKind )
  1048.             bestKindIndex = IndexOfKindInList(kindList, bestKind);
  1049.         if ( bestKindIndex == 0 )    // In case preferred kind property is bogus
  1050.             bestKindIndex = 1;
  1051.  
  1052.         bestMergeKind = BestMergeKindSetting(kindList, bestKind, mergeEditorID, nsm);
  1053.  
  1054.         // Suppress the preferred editor if it doesn't support the preferred kind
  1055.         preferredEditorID = ODGetISOStrProp(ev, contentSU, kODPropPreferredEditor, kODEditor, kODNULL, kODNULL);
  1056.         if ( preferredEditorID && bestKind && !EditorSupportsKind(nsm, preferredEditorID, bestKind) )
  1057.         {
  1058.             ODDisposePtr((ODPtr) preferredEditorID);
  1059.             preferredEditorID = kODNULL;
  1060.         }
  1061.  
  1062. #if ODDebugLinkDlgs
  1063.         somPrintf("ShowPasteAsDialog: mergeSetting = %u, best merge kind = %u\n", mergeSetting, (bestMergeKind != 0));
  1064. #endif
  1065.  
  1066.         // Set up the Kind popup items
  1067.         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, 0, kindMenu, mergeEditorID, nsm);
  1068.         GetDialogItem(dlg, kPasteAsKindPopup, &itemType, (Handle*) &kindPopupControlHandle, &kindPopupRect);
  1069.         ASSERT_CONTROL_ITEM(itemType);
  1070.         SetControlValue(kindPopupControlHandle, result->mergeSetting ? bestMergeKind : bestKindIndex);
  1071.     
  1072.         // Determine if the root storage unit is an existing part from the same draft
  1073.         // as the pasting part
  1074.  
  1075.         ODDraft* partDraft;
  1076.         // Get the draft from the part, not the frame, because the frame's storage
  1077.         // unit is null if non-persistent.
  1078.         {
  1079.             TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  1080.             partDraft = part->GetStorageUnit(ev)->GetDraft(ev);
  1081.         }
  1082.         ODBoolean contentIsPart = SUClonedFromDraft(ev, contentSU, partDraft);
  1083.  
  1084.         // Set text of static "Kind:" label
  1085.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  1086.         if ( bestKind && GetUserKindFromKind(nsm, bestKind, &gKindName) )
  1087.         {
  1088.             GetDialogItem(dlg, kPasteAsKindText, &itemType, &itemHandle, &itemRect);
  1089.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1090.             SetDialogItem(dlg, kPasteAsKindText, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  1091.         }
  1092.  
  1093.         // inactivate the "Kind:" popup if embedding is initially selected, the operation is
  1094.         // a move, and a cloned part is in the storage unit (not intrinsic content).
  1095.         if ( (!result->mergeSetting) && isMove && contentIsPart )
  1096.         {
  1097.             HideDialogItem(dlg, kPasteAsKindPopup);
  1098.         }
  1099.         else
  1100.         {
  1101.             HideDialogItem(dlg, kPasteAsKindLabel);
  1102.             HideDialogItem(dlg, kPasteAsKindText);
  1103.         }
  1104.  
  1105.         // Setup the static text for the merge editor
  1106.         DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1107.         if ( mergeEditorID && GetUserEditorFromEditor(nsm, mergeEditorID, &gEditorName) )
  1108.         {
  1109.             GetDialogItem(dlg, kPasteAsEditorText, &itemType, &itemHandle, &itemRect);
  1110.             DrawEditorNameUPP = NewUserItemProc(DrawEditorName);
  1111.             SetDialogItem(dlg, kPasteAsEditorText, userItem+itemDisable, (Handle) DrawEditorNameUPP, &itemRect);
  1112.         }
  1113.  
  1114.         // Setup the static text for the embedding editor
  1115.         // Since the contentSU will not be cloned during a move in the same document, this is a guess as to the
  1116.         // editor actually bound to the moved frame.
  1117.         if ( preferredEditorID )
  1118.             embedEditorID = ODISOStrFromCStr((char *) preferredEditorID);
  1119.         else
  1120.             embedEditorID = binding->ChooseEditorForPart(ev, contentSU, bestKind);
  1121.         
  1122.         DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1123.         if ( embedEditorID && GetUserEditorFromEditor(nsm, embedEditorID, &gEmbeddedEditorName) )
  1124.         {
  1125.             GetDialogItem(dlg, kPasteAsEmbedEditorText, &itemType, &itemHandle, &itemRect);
  1126.             DrawEmbeddedEditorNameUPP = NewUserItemProc(DrawEmbeddedEditorName);
  1127.             SetDialogItem(dlg, kPasteAsEmbedEditorText, userItem+itemDisable, (Handle) DrawEmbeddedEditorNameUPP, &itemRect);
  1128.         }
  1129.  
  1130.         // Setup the editor popup
  1131.         editorList = new EditorSet;
  1132.         editorList->InitEditorSet();
  1133.  
  1134.         refSaved = BeginUsingLibraryResources();
  1135.         editorMenu = GetMenu(kPasteAsEditorPopupMenu);
  1136.         resErr = ResError();
  1137.         EndUsingLibraryResources(refSaved);
  1138.         THROW_IF_NULL(editorMenu, resErr ? resErr : resNotFound);
  1139.  
  1140.         GetDialogItem(dlg, kPasteAsEditorPopup, &itemType, (Handle*) &editorPopupControlHandle, &editorPopupRect);
  1141.         SetupEditorMenu(bestKind, editorList, editorMenu, editorPopupControlHandle, session);
  1142.  
  1143.         if ( result->mergeSetting )
  1144.         {
  1145.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1146.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1147.         }
  1148.         else if ( isMove && contentIsPart )
  1149.         {
  1150.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1151.             HideDialogItem(dlg, kPasteAsEditorText);
  1152.         }
  1153.         else
  1154.         {
  1155.             HideDialogItem(dlg, kPasteAsEditorLabel);
  1156.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1157.             HideDialogItem(dlg, kPasteAsEditorText);
  1158.         }
  1159.         
  1160.         modalFilter = NewModalFilterProc(PasteAsFilterProc);
  1161.  
  1162.         // Display the dialog
  1163.         ShowWindow(dlg);
  1164.     
  1165.         do {
  1166.             // Remember the currently selected kind
  1167.             kindItemCurrent = (ODSShort) GetControlValue(kindPopupControlHandle);
  1168.  
  1169.             {    CUsingLibraryResources r;
  1170.                 ModalDialog(modalFilter, &itemHit);
  1171.             }
  1172.     
  1173.             switch (itemHit)
  1174.             {
  1175.             case kPasteAsLinkCheckbox:
  1176.                     result->pasteLinkSetting = !result->pasteLinkSetting;
  1177.                     GetDialogItem(dlg, itemHit, &itemType, &itemHandle, &itemRect);
  1178.                     ASSERT_CONTROL_ITEM(itemType);
  1179.                     SetControlValue((ControlHandle)itemHandle, result->pasteLinkSetting);
  1180.  
  1181.                     if ( result->pasteLinkSetting )
  1182.                     {
  1183.                         GetDialogItem(dlg, kPasteAsUpdateDisabledText, &itemType, &itemHandle, &itemRect);
  1184.                         itemRect.left += 16384;
  1185.                         itemRect.right += 16384;
  1186.                         SetDialogItem(dlg, kPasteAsUpdateDisabledText, itemType, itemHandle, &itemRect);
  1187.                         ShowDialogItem(dlg, kPasteAsUpdateText);
  1188.                     }
  1189.                     else
  1190.                     {
  1191.                         GetDialogItem(dlg, kPasteAsUpdateText, &itemType, &itemHandle, &itemRect);
  1192.                         itemRect.left += 16384;
  1193.                         itemRect.right += 16384;
  1194.                         SetDialogItem(dlg, kPasteAsUpdateText, itemType, itemHandle, &itemRect);
  1195.                         ShowDialogItem(dlg, kPasteAsUpdateDisabledText);
  1196.                     }
  1197.  
  1198.                     SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  1199.                     SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  1200.                     break;
  1201.     
  1202.             case kPasteAsAutomaticRadioBtn:
  1203.                     result->autoUpdateSetting = kODTrue;
  1204.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1205.                     break;
  1206.     
  1207.             case kPasteAsManualRadioBtn:
  1208.                     result->autoUpdateSetting = kODFalse;
  1209.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1210.                     break;
  1211.     
  1212.             case kPasteAsMergePict:
  1213.             case kPasteAsMergeRadioBtn:
  1214.                     if ( !result->mergeSetting )
  1215.                     {
  1216.                         result->mergeSetting = kODTrue;
  1217.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1218.  
  1219.                         TempODType selectedKind = kODNULL;
  1220.                         if ( kindItemCurrent <= kindList->Count(ev) )
  1221.                             selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1222.                         else
  1223.                             selectedKind = GetSelectedType(translateToList, translationIndex);
  1224.  
  1225.                         if ( !EditorSupportsKind(nsm, mergeEditorID, selectedKind) )
  1226.                         {
  1227.                             SetPopupControlValue(kindPopupControlHandle, bestMergeKind);
  1228.                             userChangedKind = kODFalse;    // Allow embed to automatically select best kind
  1229.                         }
  1230.  
  1231.                         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, mergeEditorID, nsm);
  1232.     
  1233.                         if ( isMove && contentIsPart )
  1234.                         {
  1235.                             HideDialogItem(dlg, kPasteAsKindLabel);
  1236.                             HideDialogItem(dlg, kPasteAsKindText);
  1237.                             ShowDialogItem(dlg, kPasteAsKindPopup);
  1238.                         }
  1239.                         else
  1240.                         {
  1241.                             EnablePasteAsOkButton(dlg, kindMenu);
  1242.                         }
  1243.                         
  1244.                         HideDialogItem(dlg, kPasteAsEditorPopup);
  1245.                         HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1246.                         ShowDialogItem(dlg, kPasteAsEditorLabel);
  1247.                         ShowDialogItem(dlg, kPasteAsEditorText);
  1248.                     }
  1249.                     break;
  1250.     
  1251.             case kPasteAsEmbedPict:
  1252.             case kPasteAsEmbedRadioBtn:
  1253.                     if ( result->mergeSetting )
  1254.                     {
  1255.                         result->mergeSetting = kODFalse;
  1256.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1257.     
  1258.                         // If the user has not changed the kind setting, switch to the preferred kind
  1259.                         kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1260.                         if ( !userChangedKind )
  1261.                         {
  1262.                             // Make sure item is enabled before drawing it!
  1263.                             EnableItem(kindMenu, bestKindIndex);
  1264.                             SetPopupControlValue(kindPopupControlHandle, bestKindIndex);
  1265.                             kindItemSelected = bestKindIndex;
  1266.                         }
  1267.  
  1268.                         // When embedding is chosen, determine the preferred editor, then enable the kind menu
  1269.                         ResetEditorPopup(kindList,
  1270.                                         kindItemSelected,
  1271.                                         translateToList,
  1272.                                         translationIndex,
  1273.                                         editorList,
  1274.                                         editorMenu, 
  1275.                                         editorPopupControlHandle, 
  1276.                                         session);
  1277.  
  1278.                         // Select the preferred editor if specified
  1279.                         ODSShort preferredEditorItem = IndexOfEditorInList(editorList, preferredEditorID);
  1280.                         if ( preferredEditorItem != 0 )
  1281.                             SetPopupControlValue(editorPopupControlHandle, preferredEditorItem);
  1282.  
  1283.                         if ( isMove && contentIsPart )
  1284.                         {
  1285.                             HideDialogItem(dlg, kPasteAsEditorText);
  1286.                             ShowDialogItem(dlg, kPasteAsEmbedEditorText);
  1287.                         }
  1288.                         else
  1289.                         {
  1290.                             HideDialogItem(dlg, kPasteAsEditorLabel);
  1291.                             HideDialogItem(dlg, kPasteAsEditorText);
  1292.                             ShowDialogItem(dlg, kPasteAsEditorPopup);
  1293.                         }
  1294.  
  1295.                         // Now enable the kind items
  1296.                         if ( isMove && contentIsPart )
  1297.                         {
  1298.                             HideDialogItem(dlg, kPasteAsKindPopup);
  1299.                             ShowDialogItem(dlg, kPasteAsKindLabel);
  1300.                             ShowDialogItem(dlg, kPasteAsKindText);
  1301.                         }
  1302.                         else
  1303.                         {
  1304.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1305.                             ODEditor selectedEditor = GetSelectedEditor(editorList, editorItem);
  1306.                             EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, selectedEditor, nsm);
  1307.                             ODDisposePtr((ODPtr) selectedEditor);
  1308.                             EnablePasteAsOkButton(dlg, kindMenu);
  1309.                         }
  1310.                     }
  1311.                     break;
  1312.     
  1313.             case kPasteAsKindPopup:
  1314.                     kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1315.                     if ( kindItemSelected == kindItemOthers )
  1316.                     {
  1317.                         ODUShort selectedIndex;
  1318.                         ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1319.                         ODEditor initialEditorID;
  1320.                         if ( result->mergeSetting )
  1321.                             initialEditorID = ODISOStrFromCStr((char *) mergeEditorID);
  1322.                         else
  1323.                             initialEditorID = GetSelectedEditor(editorList, editorItem);
  1324.                         ODEditor newEditorID = kODNULL;
  1325.  
  1326.                         // Return the kind popup to its current value 
  1327.                         SetPopupControlValue(kindPopupControlHandle, kindItemCurrent);
  1328.                         DeactivateModalDialog(modalFilter);
  1329.                         
  1330.                         if ( session->GetTranslation(ev)->ShowTranslateDialog(
  1331.                                                                 ev,
  1332.                                                                 translateToList,
  1333.                                                                 translationIndex,
  1334.                                                                 &selectedIndex,
  1335.                                                                 initialEditorID,
  1336.                                                                 !result->mergeSetting,
  1337.                                                                 &newEditorID) )
  1338.                         {
  1339.                             // Add translationKind to the list just above "Translate to…", 
  1340.                             //  and make it the current selection.
  1341.                             translationIndex = selectedIndex;
  1342.  
  1343.                             { TempODType translationKind = GetSelectedType(translateToList, translationIndex);
  1344.                               AddTranslationKindToMenu(translationKind, kindMenu, kindItemOthers-1, 
  1345.                                                         kindPopupHasNoTranslationKind, session);
  1346.                             }
  1347.  
  1348.                             if ( kindPopupHasNoTranslationKind )
  1349.                             {
  1350.                                 kindPopupHasNoTranslationKind = kODFalse;
  1351.                                 kindItemOthers += 1;
  1352.                             }
  1353.  
  1354.                             SetPort(dlg);
  1355.                             SetControlValue(kindPopupControlHandle, kindItemOthers-1);
  1356.                             InvalRect(&kindPopupRect);    // Redraw the popup
  1357.  
  1358.                             if ( !result->mergeSetting )
  1359.                             {
  1360.                                 ResetEditorPopup(kindList,
  1361.                                                 kindItemSelected,
  1362.                                                 translateToList,
  1363.                                                 translationIndex,
  1364.                                                 editorList,
  1365.                                                 editorMenu, 
  1366.                                                 editorPopupControlHandle, 
  1367.                                                 session);
  1368.                                 // Select editorID in the list
  1369.                                 ODSShort editorItem = IndexOfEditorInList(editorList, newEditorID);
  1370.                                 if ( editorItem != 0 )
  1371.                                     SetControlValue(editorPopupControlHandle, editorItem);
  1372.                                 InvalRect(&editorPopupRect);    // Redraw the popup
  1373.                             }
  1374.                             ODDisposePtr((ODPtr) initialEditorID);
  1375.                             ODDisposePtr((ODPtr) newEditorID);
  1376.  
  1377.                             userChangedKind = kODTrue;
  1378.                         }
  1379.                     }
  1380.                     else if ( kindItemSelected != kindItemCurrent )
  1381.                     {
  1382.                         userChangedKind = kODTrue;
  1383.                         if ( !result->mergeSetting )
  1384.                         {
  1385.                             // Remember the currently selected editor
  1386.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1387.                             TempODEditor lastEditorID = GetSelectedEditor(editorList, editorItem);
  1388.  
  1389.                             ResetEditorPopup(kindList,
  1390.                                             kindItemSelected,
  1391.                                             translateToList,
  1392.                                             translationIndex,
  1393.                                             editorList,
  1394.                                             editorMenu, 
  1395.                                             editorPopupControlHandle, 
  1396.                                             session);
  1397.  
  1398.                             // Reselect the last editor if it supports the new kind
  1399.                             TempODType selectedKind = kODNULL;
  1400.                             if ( kindItemCurrent <= kindList->Count(ev) )
  1401.                                 selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1402.                             else
  1403.                                 selectedKind = GetSelectedType(translateToList, translationIndex);
  1404.  
  1405.                             ODSShort newEditorItem = 0;
  1406.                             if ( EditorSupportsKind(nsm, lastEditorID, selectedKind) )
  1407.                             {
  1408.                                 newEditorItem = IndexOfEditorInList(editorList, lastEditorID);
  1409.                             }
  1410.                             if ( newEditorItem != 0 )
  1411.                                 SetPopupControlValue(editorPopupControlHandle, newEditorItem);
  1412.                             else
  1413.                             {
  1414.                             SetPort(dlg);
  1415.                             InvalRect(&editorPopupRect);    // Redraw the popup
  1416.                         }
  1417.                     }
  1418.                     }
  1419.                     EnablePasteAsOkButton(dlg, kindMenu);
  1420.                     break;
  1421. #ifdef _APPLEGUIDE_READY_
  1422.             case kPasteAsAGButton:
  1423.                 OpenAppleGuide();
  1424.                 break;
  1425. #endif
  1426.             default:
  1427.                     break;
  1428.             }
  1429.         } while ((itemHit != kPasteAsOKBtn) && (itemHit != kPasteAsCancelBtn));
  1430.         
  1431.         if ( itemHit == kPasteAsOKBtn )
  1432.         {
  1433.             // update from "View" popup
  1434.             if ( !result->mergeSetting )
  1435.                 result->selectedView = GetViewSelected(dlg, session);
  1436.     
  1437.             // update from "Kind" popup
  1438.             if ( (!result->mergeSetting) && isMove && contentIsPart )
  1439.             {
  1440.                 // Selected kind is the best kind
  1441.                 result->selectedKind = GetSelectedType(kindList, bestKindIndex);
  1442.             }
  1443.             else
  1444.             {
  1445.                 ODSShort kindItem = (ODSShort) GetControlValue(kindPopupControlHandle);
  1446.                 ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1447.                 if (kindItem <= kindCount)
  1448.                 {
  1449.                     result->selectedKind = GetSelectedType(kindList, kindItem);
  1450.                 }
  1451.                 else
  1452.                 {
  1453.                     result->selectedKind = GetSelectedType(translateToList, translationIndex);
  1454.                     result->translateKind = GetSelectedType(kindList, GetIndexedElement(translateFromList, translationIndex));
  1455.                 }
  1456.             }
  1457.  
  1458.             // update from "Editor" popup
  1459.             if ( (!result->mergeSetting) && (!isMove || !contentIsPart) )
  1460.             {
  1461.                 ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1462.                 result->editor = GetSelectedEditor(editorList, editorItem);
  1463.             }
  1464.         }
  1465.     
  1466.     CATCH_ALL
  1467.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  1468.         ODDisposeRoutineDescriptor(DrawDeactiveItemUPP);
  1469.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  1470.         ODDisposeRoutineDescriptor(DrawEditorNameUPP);
  1471.         ODDisposeRoutineDescriptor(DrawEmbeddedEditorNameUPP);
  1472.         ODDisposeRoutineDescriptor(modalFilter);
  1473.  
  1474.         refSaved = BeginUsingLibraryResources();
  1475.         if ( kindMenu )
  1476.         {
  1477.             DeleteMenu(kPasteAsKindPopupMenu);
  1478.             ReleaseResource((Handle) kindMenu);
  1479.         }
  1480.         if ( editorMenu )
  1481.         {
  1482.             DeleteMenu(kPasteAsEditorPopupMenu);
  1483.             ReleaseResource((Handle) editorMenu);
  1484.         }
  1485.         ODDisposeDialog(dlg);
  1486.         EndUsingLibraryResources(refSaved);
  1487.  
  1488.         ODDisposePtr((ODPtr) mergeEditorID);
  1489.         ODDisposePtr((ODPtr) embedEditorID);
  1490.         ODDisposePtr((ODPtr) preferredEditorID);
  1491.         ODDisposePtr((ODPtr) bestKind);
  1492.  
  1493.         ODDeleteObject(kindList);
  1494.         ODDeleteObject(translateToList);
  1495.         ODDeleteObject(translateFromList);
  1496.         delete editorList; editorList = kODNULL;
  1497.  
  1498.         DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1499.         DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1500.  
  1501.         SetPort(savePort);
  1502. //        RERAISE;
  1503.         err = ErrorCode();
  1504.     ENDTRY;
  1505.  
  1506.     DisposeRoutineDescriptor(DrawBoxItemUPP);
  1507.     DisposeRoutineDescriptor(DrawDeactiveItemUPP);
  1508.     DisposeRoutineDescriptor(DrawKindNameUPP);
  1509.     DisposeRoutineDescriptor(DrawEditorNameUPP);
  1510.     DisposeRoutineDescriptor(DrawEmbeddedEditorNameUPP);
  1511.     DisposeRoutineDescriptor(modalFilter);
  1512.  
  1513.     refSaved = BeginUsingLibraryResources();
  1514.     if ( kindMenu )
  1515.     {
  1516.         DeleteMenu(kPasteAsKindPopupMenu);
  1517.         ReleaseResource((Handle) kindMenu);
  1518.     }
  1519.     if ( editorMenu )
  1520.     {
  1521.         DeleteMenu(kPasteAsEditorPopupMenu);
  1522.         ReleaseResource((Handle) editorMenu);
  1523.     }
  1524.     DisposeDialog(dlg);
  1525.     EndUsingLibraryResources(refSaved);
  1526.  
  1527.     ODDisposePtr((ODPtr) mergeEditorID);
  1528.     ODDisposePtr((ODPtr) embedEditorID);
  1529.     ODDisposePtr((ODPtr) preferredEditorID);
  1530.     ODDisposePtr((ODPtr) bestKind);
  1531.  
  1532.     ODDeleteObject(kindList);
  1533.     ODDeleteObject(translateToList);
  1534.     ODDeleteObject(translateFromList);
  1535.     delete editorList; editorList = kODNULL;
  1536.  
  1537.     DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1538.     DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1539.  
  1540.     session->GetWindowState(ev)->ActivateFrontWindows(ev);
  1541.  
  1542.     SetPort(savePort);
  1543.  
  1544.     *boolResult = (itemHit == kPasteAsOKBtn);
  1545.     return err;
  1546. }
  1547.  
  1548. //------------------------------------------------------------------------------
  1549. // ResetEditorPopup
  1550. //------------------------------------------------------------------------------
  1551.  
  1552. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  1553.                                 ODUShort kindIndex,
  1554.                                 ODTypeList* translateToList,
  1555.                                 ODUShort translateToIndex,
  1556.                                 EditorSet* editorList,
  1557.                                 MenuHandle editorMenu, 
  1558.                                 ControlHandle popupCtlHndl, 
  1559.                                 ODSession* session)
  1560. {
  1561.     Environment* ev = somGetGlobalEnvironment();
  1562.     TempODType kind = kODNULL;
  1563.  
  1564.     ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1565.     if (kindIndex <= kindCount)
  1566.         kind = GetSelectedType(kindList, kindIndex);
  1567.     else
  1568.         kind = GetSelectedType(translateToList, translateToIndex);
  1569.  
  1570.     editorList->RemoveAllEditors();
  1571.     SetupEditorMenu(kind,
  1572.                     editorList,
  1573.                     editorMenu,
  1574.                     popupCtlHndl,
  1575.                     session);
  1576. }
  1577.  
  1578. //------------------------------------------------------------------------------
  1579. // PrepareToDrawGray
  1580. //------------------------------------------------------------------------------
  1581. //
  1582. // Sets the foreground color to the best color midway between the forground and
  1583. // background colors; usually gray.  If no intermediate gray is available (4 or
  1584. // fewer colors available), the pen pattern is set to draw gray.
  1585.  
  1586. ODStatic Boolean PrepareToDrawGray(DialogPtr theDialog, short theItem, RGBColor* fgSaveColor)
  1587. {
  1588.     Boolean result = false;
  1589.     const short kColorPort = 0xC000;
  1590.     
  1591.     Boolean isColorPort = ((((CGrafPtr)theDialog)->portVersion & kColorPort) == kColorPort);
  1592.     
  1593.     if ( isColorPort )
  1594.     {
  1595.         RGBColor    fgNewColor;
  1596.         RGBColor    bgColor;
  1597.  
  1598.         Rect         itemRect;
  1599.         Handle        itemHandle;
  1600.         short        itemKind;
  1601.  
  1602.         GetBackColor(&bgColor);
  1603.         GetForeColor(fgSaveColor);
  1604.         fgNewColor = *fgSaveColor;
  1605.         
  1606.         GetDialogItem(theDialog, kPasteAsOKBtn, &itemKind, &itemHandle, &itemRect);
  1607.  
  1608.         Rect globalRect = itemRect;
  1609.         LocalToGlobal((Point *)&(globalRect.top));
  1610.         LocalToGlobal((Point *)&(globalRect.bottom));
  1611.         GDHandle targetDevice = GetMaxDevice(&globalRect);
  1612.         
  1613.         result = GetGray(targetDevice, &bgColor, &fgNewColor);
  1614.  
  1615.         if ( result )
  1616.             RGBForeColor(&fgNewColor);
  1617.     }
  1618.     
  1619.     if ( !result )
  1620.     {
  1621. #ifdef THINK_CPLUS
  1622.         PenPat(ODQDGlobals.gray);
  1623. #else
  1624.         PenPat(&ODQDGlobals.gray);
  1625. #endif
  1626.     }
  1627.  
  1628.     return result;
  1629. }
  1630.  
  1631. //------------------------------------------------------------------------------
  1632. // DrawDeactivePICTItem
  1633. //------------------------------------------------------------------------------
  1634. //
  1635. // Draws a dimmed image of the preceeding dialog item, which should be
  1636. // beyond the visible area of the dialog, in this item's rectangle.
  1637.  
  1638. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem)
  1639. {
  1640.     Rect         itemRect, otherRect;
  1641.     Handle        itemHandle, otherHandle;
  1642.     short        itemKind, otherKind;
  1643.  
  1644.     WindowPtr    savePort;
  1645.     PenState    savePen;
  1646.     
  1647.     RGBColor    fgSaveColor;
  1648.     Boolean        isColor;
  1649.  
  1650.     GetPort(&savePort);
  1651.     SetPort(theDialog);
  1652.     GetPenState(&savePen);
  1653.     PenNormal();
  1654.  
  1655.     // Get this dialog item
  1656.     GetDialogItem(theDialog, theItem, &itemKind, &itemHandle, &itemRect);
  1657.  
  1658.     // Get the dialog item to be drawn disabled
  1659.     GetDialogItem(theDialog, theItem-1, &otherKind, &otherHandle, &otherRect);
  1660.     if ( (otherKind & ~itemDisable) == picItem )
  1661.     {
  1662.         DrawPicture((PicHandle) otherHandle, &itemRect);
  1663.         isColor = PrepareToDrawGray(theDialog, theItem, &fgSaveColor);
  1664.         if ( isColor )
  1665.             PenMode(addMax);
  1666.         else
  1667.             PenMode(patBic);
  1668.         PaintRect(&itemRect);
  1669.         if ( isColor )
  1670.             RGBForeColor(&fgSaveColor);
  1671.     }
  1672.  
  1673.     SetPenState(&savePen);
  1674.     SetPort(savePort);
  1675. }
  1676.  
  1677. //------------------------------------------------------------------------------
  1678. // InitItemActive
  1679. //------------------------------------------------------------------------------
  1680.  
  1681. ODStatic void InitItemActive(
  1682.                     DialogPtr    dlg,
  1683.                     short        itemNumber,
  1684.                     UserItemUPP    itemUPP,
  1685.                     ODBoolean    itemActive)
  1686. {
  1687.     Rect         itemRect, otherRect;
  1688.     Handle        itemHandle, otherHandle;
  1689.     short        itemKind, otherKind;
  1690.  
  1691.     // Get the rectangle from the actual item
  1692.     GetDialogItem(dlg, itemNumber, &otherKind, &otherHandle, &otherRect);
  1693.  
  1694.     // Establish the draw routine and rectangle for the user item
  1695.     GetDialogItem(dlg, itemNumber+1, &itemKind, &itemHandle, &itemRect);
  1696.     SetDialogItem(dlg, itemNumber+1, itemKind, (Handle)itemUPP, &otherRect);
  1697.  
  1698.     if ( itemActive )
  1699.         HideDialogItem(dlg, itemNumber+1);
  1700.     else
  1701.         HideDialogItem(dlg, itemNumber);
  1702. }
  1703.  
  1704. //------------------------------------------------------------------------------
  1705. // SetControlActive
  1706. //------------------------------------------------------------------------------
  1707. ODStatic void SetControlActive(
  1708.                     DialogPtr    dlg,
  1709.                     short        itemNumber,
  1710.                     ODBoolean    itemActive)
  1711. {
  1712.     short        itemType;
  1713.     Handle        itemHandle;
  1714.     Rect        itemRect;
  1715.  
  1716.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  1717.     ASSERT_CONTROL_ITEM(itemType);
  1718.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  1719. }
  1720.  
  1721. //------------------------------------------------------------------------------
  1722. // BestContentKind
  1723. //------------------------------------------------------------------------------
  1724. ODStatic ODType BestContentKind(ODStorageUnit* contentSU)
  1725. {
  1726.     Environment* ev = somGetGlobalEnvironment();
  1727.  
  1728.     ODType bestKind = ODGetISOStrProp(ev, contentSU, kODPropPreferredKind, kODISOStr, kODNULL, kODNULL);
  1729.  
  1730.     if ( bestKind == kODNULL )
  1731.     {
  1732.         if (contentSU->Exists(ev, kODPropContents, (ODValueType)kODNULL, 1))
  1733.         {
  1734.             contentSU->Focus(ev, kODPropContents, kODPosUndefined, (ODValueType)kODNULL, 1, kODPosUndefined);
  1735.             bestKind = contentSU->GetType(ev);
  1736.         }
  1737.     }
  1738.     
  1739.     return bestKind;
  1740. }
  1741.  
  1742. //------------------------------------------------------------------------------
  1743. // SetLinkUpdateUpdateControls
  1744. //------------------------------------------------------------------------------
  1745. ODStatic void SetLinkUpdateUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  1746. {
  1747.     short    itemType;
  1748.     Handle    itemHandle;
  1749.     Rect    itemRect;
  1750.  
  1751.     GetDialogItem(dlg, kLinkInfoOnSaveRadioBtn, &itemType, &itemHandle, &itemRect);
  1752.     ASSERT_CONTROL_ITEM(itemType);
  1753.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  1754.     GetDialogItem(dlg, kLinkInfoManualRadioBtn, &itemType, &itemHandle, &itemRect);
  1755.     ASSERT_CONTROL_ITEM(itemType);
  1756.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  1757. }
  1758.  
  1759. //------------------------------------------------------------------------------
  1760. // LinkInfoFilterProc
  1761. //------------------------------------------------------------------------------
  1762.  
  1763. static pascal Boolean
  1764. LinkInfoFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit)
  1765. {    
  1766.     // If the event is a deactivate event, the ok button must be deactivated
  1767.     // before the surrounding outline is drawn so it is drawn dim.
  1768.     ODBoolean rslt = ODButtonKeyFilterProc(dialog,event,itemHit);
  1769.  
  1770.     if ( event->what == activateEvt )
  1771.     {
  1772.         ODOutlineDefaultButtonDrawProc(dialog, kLinkInfoDefaultButtonItem);
  1773.     }
  1774.  
  1775.     return rslt;
  1776. }
  1777.  
  1778. //------------------------------------------------------------------------------
  1779. // ShowLinkInfo
  1780. //------------------------------------------------------------------------------
  1781.  
  1782. ODStatic ODBoolean ShowLinkInfo(
  1783.                         DialogPtr              dlg,
  1784.                         ConstStr255Param    creationDate,
  1785.                         ConstStr255Param    creationTime,
  1786.                         ConstStr255Param    modificationDate,
  1787.                         ConstStr255Param    modificationTime,
  1788.                         ODBoolean            needsUpdate,
  1789.                         ODLinkInfoResult*    infoResult
  1790.                         )
  1791. {
  1792.     short    itemHit;
  1793.  
  1794.     ParamText(creationDate, creationTime, modificationDate, modificationTime);
  1795.  
  1796.     ShowWindow(dlg);
  1797.     
  1798.     ModalFilterUPP modalFilter = NewModalFilterProc(LinkInfoFilterProc);
  1799.  
  1800.     do {
  1801.         ODSLong refSaved = BeginUsingLibraryResources();
  1802.         ModalDialog(modalFilter, &itemHit);
  1803.         EndUsingLibraryResources(refSaved);
  1804.  
  1805.         switch (itemHit)
  1806.         {
  1807.         case kLinkInfoManualRadioBtn :
  1808.             if ( infoResult->autoUpdate )
  1809.             {
  1810.                 infoResult->autoUpdate = kODFalse;
  1811.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1812.                 SetControlActive(dlg, kLinkInfoUpdateBtn, needsUpdate);
  1813.             }
  1814.             break;
  1815.             
  1816.         case kLinkInfoOnSaveRadioBtn :
  1817.             if ( !infoResult->autoUpdate )
  1818.             {
  1819.                 infoResult->autoUpdate = kODTrue;
  1820.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1821.                 SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  1822.             }
  1823.             break;
  1824. #ifdef _APPLEGUIDE_READY_
  1825.         case kLinkInfoAGButton:
  1826.             OpenAppleGuide();
  1827.             break;
  1828. #endif
  1829.         }
  1830.     } while ((itemHit != kLinkInfoOKBtn) && (itemHit != kLinkInfoCancelBtn) &&
  1831.              (itemHit != kLinkInfoUpdateBtn) && (itemHit != kLinkInfoBreakLinkBtn) &&
  1832.              (itemHit != kLinkInfoFindSrcBtn));
  1833.  
  1834.     switch (itemHit) {
  1835.     case kLinkInfoOKBtn:
  1836.             infoResult->action = kODLinkInfoOk;
  1837.             break;
  1838.     case kLinkInfoUpdateBtn:
  1839.             infoResult->action = kODLinkInfoUpdateNow;
  1840.             break;
  1841.     case kLinkInfoBreakLinkBtn:
  1842.             infoResult->action = kODLinkInfoBreakLink;
  1843.             break;
  1844.     case kLinkInfoFindSrcBtn:
  1845.             infoResult->action = kODLinkInfoFindSource;
  1846.             break;
  1847.     default:
  1848.             infoResult->action = kODLinkInfoCancel;
  1849.             break;
  1850.     }
  1851.  
  1852.     ODDisposeRoutineDescriptor(modalFilter);
  1853.  
  1854.     return (itemHit != kLinkInfoCancelBtn);
  1855. }
  1856.  
  1857. //------------------------------------------------------------------------------
  1858. // DrawKindName
  1859. //------------------------------------------------------------------------------
  1860.  
  1861. pascal void DrawKindName(DialogPtr dialog, SInt16 item)
  1862. {
  1863.     short    itemType;
  1864.     Handle    itemHandle;
  1865.     Rect    itemRect;
  1866.  
  1867.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  1868.  
  1869.     DrawITextInDlogBox(gKindName, &itemRect, dialog, kODTrue);
  1870. }
  1871.  
  1872. //------------------------------------------------------------------------------
  1873. // ShowLinkSourceInfo
  1874. //------------------------------------------------------------------------------
  1875.  
  1876. ODError ShowLinkSourceInfoEx(
  1877.                 ODBaseLinkSource*    linkSource,
  1878.                 ODUpdateID            change,
  1879.                 ODBoolean            changesAllowed,
  1880.                 ODLinkInfoResult*    infoResult,
  1881.                 ODBoolean*            boolResult)
  1882. {
  1883.     ODError err = noErr;
  1884.     Environment* ev = somGetGlobalEnvironment();
  1885.  
  1886.     WindowPtr    savePort;                        ODVolatile(savePort);
  1887.     GetPort(&savePort);
  1888.     ODSLong        refSaved;
  1889.  
  1890.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  1891.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  1892.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  1893.     short        itemType;
  1894.     Handle        itemHandle;
  1895.     Rect        itemRect;
  1896.     Str255        creationDate, modificationDate;
  1897.     Str255        creationTime, modificationTime;
  1898.     ODType        kind;
  1899.     ODBoolean    needsUpdate;
  1900. //    ODBoolean    result;
  1901.  
  1902.     TRY
  1903.         ODSession* session = linkSource->GetStorageUnit(ev)->GetSession(ev);
  1904.         InitBindingNamespaceUtils(session);
  1905.         
  1906.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  1907.         
  1908.         {
  1909.             CUsingLibraryResources r;
  1910.             dlg = ODGetNewDialog(ev, kLinkSrcInfoDlgID, session, kNoDefaultButton);
  1911.             THROW_IF_NULL(dlg);
  1912.         }
  1913.  
  1914.         DialogSetUpAppleGuide( dlg, kLinkInfoAGButton );
  1915.         SetPort(dlg);
  1916.         
  1917.         {    CUsingLibraryResources r;
  1918.             SetDialogTextStyle(dlg, kLinkSrcInfoDlgID, smCurrentScript);
  1919.         }
  1920.     
  1921.         // Set the draw routine for the default button outline item
  1922.         GetDialogItem(dlg, kLinkInfoDefaultButtonItem, &itemType, &itemHandle, &itemRect);
  1923.         SetDialogItem(dlg, kLinkInfoDefaultButtonItem, itemType, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  1924.         
  1925.         // Vertical and horizontal lines need to be drawn
  1926.         GetDialogItem(dlg, kLinkInfoSeparator, &itemType, &itemHandle, &itemRect);
  1927.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  1928.         SetDialogItem(dlg, kLinkInfoSeparator, itemType, (Handle)DrawBoxItemUPP, &itemRect);
  1929.         
  1930.         ODLinkKey key;
  1931.         if (linkSource->Lock(ev, 0, &key))
  1932.         {
  1933.             TRY
  1934.                 ODStorageUnit*    contentSU = linkSource->GetContentStorageUnit(ev, key);
  1935.         
  1936.                 // Set up kind
  1937.                 kind = BestContentKind(contentSU);
  1938.                 DisposeGlobalODNameAndZeroPtr(&gKindName);
  1939.                 if ( kind && GetUserKindFromKind(nsm, kind, &gKindName) )
  1940.                 {
  1941.                     GetDialogItem(dlg, kLinkInfoKind, &itemType, &itemHandle, &itemRect);
  1942.                     DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1943.                     SetDialogItem(dlg, kLinkInfoKind, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  1944.                 }
  1945.                 ODDisposePtr((ODPtr) kind);
  1946.     
  1947.                 // Set up creation date
  1948.                 SetDateTimeStrings(ODGetCreationDate(ev, ODGetSUFromPstObj(ev, linkSource)),
  1949.                                     creationDate, creationTime);
  1950.                 
  1951.                 // Set up modified date
  1952.                 SetDateTimeStrings(linkSource->GetChangeTime(ev), modificationDate, modificationTime);
  1953.             CATCH_ALL
  1954.                 linkSource->Unlock(ev, key);
  1955.                 RERAISE;
  1956.             ENDTRY
  1957.     
  1958.             linkSource->Unlock(ev, key);
  1959.         }
  1960.         
  1961.         // Set up Send Updates
  1962.         SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1963.         
  1964.         needsUpdate = (change == kODUnknownUpdate) || (change != linkSource->GetUpdateID(ev));
  1965.         
  1966.         // Disable Update Now button if updates are automatic or link is up to date.
  1967.         if ( infoResult->autoUpdate || !needsUpdate )
  1968.         {
  1969.             GetDialogItem(dlg, kLinkInfoUpdateBtn, &itemType, &itemHandle, &itemRect);
  1970.             ASSERT_CONTROL_ITEM(itemType);
  1971.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  1972.         }
  1973.     
  1974.         // Disable some items if changes are not allowed or draft is read only
  1975.         if ( !changesAllowed || DraftIsReadOnly(ev, linkSource->GetStorageUnit(ev)) )
  1976.         {
  1977.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  1978.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  1979.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  1980.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  1981.         }
  1982.  
  1983.         *boolResult = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  1984.                                 modificationTime, needsUpdate, infoResult);
  1985.     
  1986.     CATCH_ALL
  1987.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  1988.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  1989.  
  1990.         refSaved = BeginUsingLibraryResources();
  1991.         ODDisposeDialog(dlg);
  1992.         EndUsingLibraryResources(refSaved);
  1993.  
  1994.         SetPort(savePort);
  1995. //        RERAISE;
  1996.         err = ErrorCode();
  1997.     ENDTRY
  1998.  
  1999.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2000.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2001.  
  2002.     refSaved = BeginUsingLibraryResources();
  2003.     ODDisposeDialog(dlg);
  2004.     EndUsingLibraryResources(refSaved);
  2005.  
  2006.     SetPort(savePort);
  2007.  
  2008.     return err;
  2009. }
  2010.                 
  2011. //------------------------------------------------------------------------------
  2012. // SetDateTimeStrings
  2013. //------------------------------------------------------------------------------
  2014.  
  2015. ODStatic void SetDateTimeStrings(
  2016.                     ODULong        dateTime,
  2017.                     Str255        dateString, 
  2018.                     Str255        timeString)
  2019. {
  2020.     if ( dateTime == 0 )
  2021.     {
  2022.         CUsingLibraryResources r;
  2023.  
  2024.         StringHandle str = GetString(kODLinkInfoStrUnknownID);
  2025.         if ( str != kODNULL )
  2026.         {
  2027.             ODLockHandle((ODHandle) str);
  2028.             ODBlockMove((ODPtr) *str, (ODPtr) dateString, (ODULong) (*str[0])+1);
  2029.             ODUnlockHandle((ODHandle) str);
  2030.             ReleaseResource((Handle) str);
  2031.         }
  2032.         else
  2033.         {
  2034.             dateString[0] = (char) 0;
  2035.         }
  2036.         timeString[0] = (char) 0;
  2037.     }
  2038.     else
  2039.     {
  2040.         DateString(dateTime, abbrevDate, dateString, kODNULL);
  2041.         TimeString(dateTime, kODFalse, timeString, kODNULL);
  2042.     }
  2043. }
  2044.  
  2045. //------------------------------------------------------------------------------
  2046. // DraftIsReadOnly
  2047. //------------------------------------------------------------------------------
  2048. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su)
  2049. {
  2050.     return (!HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
  2051. }
  2052.  
  2053. //------------------------------------------------------------------------------
  2054. // ShowLinkDestinationInfo
  2055. //------------------------------------------------------------------------------
  2056.  
  2057. ODError ShowLinkDestinationInfoEx(
  2058.                 ODBaseLink*            link,
  2059.                 ODLinkInfo*         info,
  2060.                 ODBoolean            changesAllowed,
  2061.                 ODLinkInfoResult*    infoResult,
  2062.                 ODBoolean*            boolResult)
  2063. {
  2064.     ODError err = noErr;
  2065.     Environment* ev = somGetGlobalEnvironment();
  2066.  
  2067.     WindowPtr    savePort;                        ODVolatile(savePort);
  2068.     GetPort(&savePort);
  2069.     ODSLong        refSaved;
  2070.  
  2071.     short          itemType;
  2072.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  2073.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  2074.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  2075.     Handle        itemHandle;
  2076.     Rect        itemRect;
  2077.     Str255        creationDate, modificationDate;
  2078.     Str255        creationTime, modificationTime;
  2079.     ODBoolean    needsUpdate;
  2080. //    ODBoolean    result;
  2081.  
  2082.     TRY
  2083.         ODSession* session = link->GetStorageUnit(ev)->GetSession(ev);
  2084.         InitBindingNamespaceUtils(session);
  2085.         
  2086.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  2087.  
  2088.         {
  2089.             CUsingLibraryResources r;
  2090.             dlg = ODGetNewDialog(ev, kLinkDstInfoDlgID, session, kNoDefaultButton);
  2091.             THROW_IF_NULL(dlg);
  2092.         }
  2093.  
  2094.         DialogSetUpAppleGuide( dlg, kLinkInfoAGButton );
  2095.         SetPort(dlg);    
  2096.  
  2097.         {    CUsingLibraryResources r;
  2098.             SetDialogTextStyle(dlg, kLinkDstInfoDlgID, smCurrentScript);
  2099.         }
  2100.     
  2101.         // Set the draw routine for the default button outline item
  2102.         GetDialogItem(dlg, kLinkInfoDefaultButtonItem, &itemType, &itemHandle, &itemRect);
  2103.         SetDialogItem(dlg, kLinkInfoDefaultButtonItem, itemType, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  2104.         
  2105.         // Vertical and horizontal lines need to be drawn
  2106.         GetDialogItem(dlg, kLinkInfoSeparator, &itemType, &itemHandle, &itemRect);
  2107.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  2108.         SetDialogItem(dlg, kLinkInfoSeparator, itemType, (Handle) DrawBoxItemUPP, &itemRect);
  2109.         
  2110.         // Set up kind
  2111.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  2112.         if ( info->kind && GetUserKindFromKind(nsm, info->kind, &gKindName) )
  2113.         {
  2114.             GetDialogItem(dlg, kLinkInfoKind, &itemType, &itemHandle, &itemRect);
  2115.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  2116.             SetDialogItem(dlg, kLinkInfoKind, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  2117.         }
  2118.  
  2119.         // Set up creation date
  2120.         SetDateTimeStrings(info->creationTime, creationDate, creationTime);
  2121.         
  2122.         // Set up modified date
  2123.         SetDateTimeStrings(info->changeTime, modificationDate, modificationTime);
  2124.  
  2125.         // Set up Send Updates
  2126.         SetLinkUpdateUpdateControls(dlg, info->autoUpdate);
  2127.         
  2128.         needsUpdate = (info->change == kODUnknownUpdate) || (info->change != link->GetUpdateID(ev));
  2129.         
  2130.         // Disable Update Now button if updates are automatic or destination is up to date.
  2131.         if ( info->autoUpdate || !needsUpdate )
  2132.         {
  2133.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2134.         }
  2135.  
  2136.         // Disable some items if changes are not allowed or draft is read only
  2137.         if ( !changesAllowed || DraftIsReadOnly(ev, link->GetStorageUnit(ev)) )
  2138.         {
  2139.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  2140.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  2141.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  2142.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2143.         }
  2144.  
  2145.         *boolResult = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  2146.                                 modificationTime, needsUpdate, infoResult);
  2147.  
  2148.     CATCH_ALL
  2149.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2150.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2151.  
  2152.         refSaved = BeginUsingLibraryResources();
  2153.         ODDisposeDialog(dlg);
  2154.         EndUsingLibraryResources(refSaved);
  2155.  
  2156.         SetPort(savePort);
  2157. //        RERAISE;
  2158.         err = ErrorCode();
  2159.     ENDTRY
  2160.  
  2161.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2162.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2163.  
  2164.     refSaved = BeginUsingLibraryResources();
  2165.     ODDisposeDialog(dlg);
  2166.     EndUsingLibraryResources(refSaved);
  2167.  
  2168.     SetPort(savePort);
  2169.  
  2170.     return err;
  2171. }
  2172.  
  2173.